1
//--------------------------------------------------------------------------
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 // File: AggregateExceptionExtensions.cs
7 //--------------------------------------------------------------------------
9 using System
.Collections
.Generic
;
13 /// <summary>Extension methods for AggregateException.</summary>
14 public static class AggregateExceptionExtensions
16 /// <summary>Invokes a handler on each Exception contained by this AggregateException.</summary>
17 /// <param name="aggregateException">The AggregateException.</param>
18 /// <param name="predicate">
19 /// The predicate to execute for each exception. The predicate accepts as an argument the Exception
20 /// to be processed and returns a Boolean to indicate whether the exception was handled.
22 /// <param name="leaveStructureIntact">
23 /// Whether the rethrown AggregateException should maintain the same hierarchy as the original.
25 public static void Handle(
26 this AggregateException aggregateException
,
27 Func
<Exception
, bool> predicate
, bool leaveStructureIntact
)
29 if (aggregateException
== null) throw new ArgumentNullException("aggregateException");
30 if (predicate
== null) throw new ArgumentNullException("predicate");
32 // If leaveStructureIntact, use this implementation
33 if (leaveStructureIntact
)
35 var result
= HandleRecursively(aggregateException
, predicate
);
36 if (result
!= null) throw result
;
38 // Otherwise, default back to the implementation on AggregateException
39 else aggregateException
.Handle(predicate
);
42 private static AggregateException
HandleRecursively(
43 AggregateException aggregateException
, Func
<Exception
, bool> predicate
)
45 // Maintain a list of exceptions to be rethrown
46 List
<Exception
> innerExceptions
= null;
48 // Loop over all of the inner exceptions
49 foreach(var inner
in aggregateException
.InnerExceptions
)
51 // If the inner exception is itself an aggregate, process recursively
52 AggregateException innerAsAggregate
= inner
as AggregateException
;
53 if (innerAsAggregate
!= null)
55 // Process recursively, and if we get back a new aggregate, store it
56 AggregateException newChildAggregate
= HandleRecursively(innerAsAggregate
, predicate
);
57 if (newChildAggregate
!= null)
59 if (innerExceptions
!= null) innerExceptions
= new List
<Exception
>();
60 innerExceptions
.Add(newChildAggregate
);
63 // Otherwise, if the exception does not match the filter, store it
64 else if (!predicate(inner
))
66 if (innerExceptions
!= null) innerExceptions
= new List
<Exception
>();
67 innerExceptions
.Add(inner
);
71 // If there are any remaining exceptions, return them in a new aggregate.
72 return innerExceptions
.Count
> 0 ?
73 new AggregateException(aggregateException
.Message
, innerExceptions
) :